package com.cq.hd.order.factory;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cq.hd.common.constant.OrderNoteConstant;
import com.cq.hd.common.enums.biz.*;
import com.cq.hd.common.response.Throw;
import com.cq.hd.common.utils.NoUtils;
import com.cq.hd.member.api.TbAppUserApi;
import com.cq.hd.member.api.TbBusinessMerchantApi;
import com.cq.hd.member.api.vo.*;
import com.cq.hd.order.api.dto.ActiveEnrollInfoSonDto;
import com.cq.hd.order.api.dto.CreateOrderDto;
import com.cq.hd.order.api.dto.OrderCommissionDto;
import com.cq.hd.order.api.vo.CreateOrderVo;
import com.cq.hd.order.mapper.TbOrderItemMapper;
import com.cq.hd.order.mapper.TbOrderMapper;
import com.cq.hd.order.po.TbOrderItemPo;
import com.cq.hd.order.po.TbOrderPo;
import com.cq.hd.order.service.PftService;
import com.cq.hd.order.service.TbOrderService;
import com.cq.hd.order.validator.ActiveOrderEnrollInfoValidator;
import com.cq.hd.product.api.TbActiveApi;
import com.cq.hd.product.api.dto.*;
import com.cq.hd.product.api.vo.ActiveRedPacketBillPageVo;
import com.cq.hd.product.api.vo.ActiveVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
public class GroupEnrollOrderHandler extends AbstractOrderHandler {

    @Autowired
    private TbOrderMapper orderMapper;

    @Autowired
    private TbOrderItemMapper orderItemMapper;

    @Autowired
    private TbBusinessMerchantApi businessMerchantApi;

    @Autowired
    private TbActiveApi activeApi;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private PftService pftService;

    @Autowired
    private TbAppUserApi appUserApi;

    @Autowired
    private TbOrderService orderService;

    @Override
    protected Integer getType() {
        return ActiveTypeEnum.GROUP_ENROLL.getValue();
    }

    @Override
    public CreateOrderVo createOrder(CreateOrderDto createOrderDto, ActiveVo activeVo) {
        String code = createOrderDto.getCode();
        Long redPacketBillId = createOrderDto.getRedPacketBillId();
        Integer orderNum = createOrderDto.getOrderNum();
        Long userId = createOrderDto.getUserId();
        Long activeId = createOrderDto.getActiveId();

        // 是否是零元购活动（1-不是，2-是）
        Integer zeroState = activeVo.getZeroState();
        // 活动商品列表(团购)
        List<ActiveGoodsSonDto> activeGoods = activeVo.getActiveGoods();
        // 多件多折列表(团购)
        List<ActiveDiscountSonDto> activeDiscounts = activeVo.getActiveDiscount();
        // 活动商品补贴列表(团购)
        List<ActiveGoodsSubsidySonDto> activeGoodsSubsidy = activeVo.getActiveGoodsSubsidy();

        Long businessId = activeVo.getBusinessId();
        // 活动价格
        BigDecimal activePrice = activeVo.getActivePrice();
        // 折扣
        BigDecimal discount = null;

        LocalDateTime now = LocalDateTime.now();
        Integer activeState = activeVo.getActiveState();
        LocalDateTime startTime = activeVo.getStartTime();
        LocalDateTime endTime = activeVo.getEndTime();
        if (startTime.compareTo(now) > 0) {
            activeState = ActiveStateEnum.NO_START.getValue();
        } else if (endTime.compareTo(now) <= 0) {
            activeState = ActiveStateEnum.ENDED.getValue();
        } else if (startTime.compareTo(now) <= 0 && endTime.compareTo(now) > 0) {
            activeState = ActiveStateEnum.IN_PROGRESS.getValue();
        }

        if (ActiveStateEnum.ENDED.getValue().equals(activeState)) {
            Throw.isBusinessException("活动已结束");
        }

        if (ActiveStateEnum.NO_START.getValue().equals(activeState)) {
            Throw.isBusinessException("活动未开始");
        }

        // 判断活动的库存是否充足
        Integer remainStock = activeVo.getRemainStock();
        if (remainStock - orderNum < 0) {
            Throw.isBusinessException("活动库存不足");
        }

        // 限购数量
        Integer limitBuyNum = activeVo.getLimitBuyNum();
        // 查询下单用户的待支付，待核销、核销中、已核销、已完成的该活动的订单数
        Integer totalOrderCount = orderService.userActiveOrderCount(userId, activeId);
        if (limitBuyNum != null && limitBuyNum > 0 && totalOrderCount != null) {
            int canOrderNum = limitBuyNum - totalOrderCount;
            if (orderNum > canOrderNum) {
                Throw.isBusinessException("已超限购个数");
            }
        }

        // 活动是否有开启多件多折规则，有就提取折扣
        Integer discountState = activeVo.getDiscountState();
        if (DiscountStateEnum.OPEN.getValue().equals(discountState)) {
            // 根据活动id查找多件多折配置
            if (!CollectionUtils.isEmpty(activeDiscounts)) {
                // 根据件数倒序
                activeDiscounts = activeDiscounts.stream()
                        .sorted(Comparator.comparing(ActiveDiscountSonDto::getNum).reversed())
                        .collect(Collectors.toList());
                for (ActiveDiscountSonDto activeDiscountVo : activeDiscounts) {
                    Integer num = activeDiscountVo.getNum();
                    if (orderNum >= num) {
                        discount = activeDiscountVo.getDiscount().divide(new BigDecimal("10"), 4, BigDecimal.ROUND_HALF_UP);
                        break;
                    }
                }
            }
        }

        // 校验报名信息
        ActiveOrderEnrollInfoValidator.validate(createOrderDto, activeVo);

        // 订单总额=活动价格*下单数量
        BigDecimal orderPrice = activePrice.multiply(new BigDecimal(String.valueOf(orderNum)));

        // 校验红包数据
        ActiveRedPacketBillPageVo activeRedPacketBillPageVo = getRedPacketBill(redPacketBillId, userId, activeId, totalOrderCount, orderPrice);
        BigDecimal redPacketAmt = BigDecimal.ZERO;
        if (activeRedPacketBillPageVo != null) {
            redPacketAmt = activeRedPacketBillPageVo.getAmt();
        }

        // 优惠金额（打折优惠=订单总额-订单总额*折扣）
        BigDecimal discountAmt = discount == null ? BigDecimal.ZERO : orderPrice.subtract(orderPrice.multiply(discount));
        // 实付金额=订单总额-红包金额-优惠金额
        BigDecimal payPrice = orderPrice.subtract(redPacketAmt).subtract(discountAmt);

        // 商家是否有开启积分商城，有的话，用户下单可以拿积分，经纪人分销可以拿积分
        BusinessPointsMallSettingsVo pointsMallSettingsVo = getPointsMallSettings(businessId);
        BigDecimal distributionPointsRate = pointsMallSettingsVo.getDistribution(); // 分销活动，每获得1元佣金，奖励x积分
        BigDecimal consumePointsRate = pointsMallSettingsVo.getConsume(); // 每消费1元，奖励x积分

        // 需要查询code是否有效，获取经纪人id和推广经济类型
        OrderCommissionDto orderCommissionDto = new OrderCommissionDto();
        orderCommissionDto.setCode(code);
        orderCommissionDto.setUserId(userId);
        orderCommissionDto.setOrderPrice(orderPrice);
        orderCommissionDto.setPayPrice(payPrice);
        orderCommissionDto.setOrderNum(orderNum);
        orderCommissionDto = calOrderCommission(orderCommissionDto, activeVo, distributionPointsRate);
        // 实际全核销佣金金额=活动价格*佣金比例=固定佣金金额*下单数量
        BigDecimal actualCommissionAmt = orderCommissionDto.getActualCommissionAmt();
        // 计算佣金类型(0-无,1-固定佣金,2-固定佣金比例，3-专属佣金比例)
        Integer calCommissionType = orderCommissionDto.getCalCommissionType();
        // 商家跟一级经纪人专属佣金比例
        BigDecimal exclusiveCommissionRate = orderCommissionDto.getExclusiveCommissionRate();
        // 二级经纪人可得的佣金比例
        BigDecimal subAgentCommissionRate = orderCommissionDto.getSubAgentCommissionRate();
        // 二级经纪人可得佣金
        BigDecimal subAgentCommissionAmt = orderCommissionDto.getSubAgentCommissionAmt();
        String otherEquity = orderCommissionDto.getOtherEquity();
        Long agentId = orderCommissionDto.getAgent1Id(); // 一级经纪人id
        Long agent2Id = orderCommissionDto.getAgent2Id(); // 二级经纪人id
        // 下单用户可得积分
        BigDecimal userPointsAmt = payPrice.multiply(consumePointsRate);
        // 一级经纪人可得积分
        BigDecimal agentPointsAmt = orderCommissionDto.getAgentPointsAmt();
        // 二级经纪人可得积分
        BigDecimal subAgentPointsAmt = orderCommissionDto.getSubAgentPointsAmt();
        // 积分结算状态：0无需结算 1待结算 2已结算
        int pointsSettleState = 0;
        if (userPointsAmt.compareTo(BigDecimal.ZERO) > 0 || agentPointsAmt.compareTo(BigDecimal.ZERO) > 0|| subAgentPointsAmt.compareTo(BigDecimal.ZERO) > 0) {
            pointsSettleState = 1;
        }

        // 商品总额=商品金额*商品数量
        BigDecimal totalGoodsPrice = getTotalGoodsPrice(activeGoods, orderNum);

        // 订单收入(当实付金额大于商品总额，订单收入=实付金额-商品总额-全核销佣金)
        BigDecimal orderIncomeAmt = payPrice.subtract(totalGoodsPrice).subtract(actualCommissionAmt);
        if (orderIncomeAmt.compareTo(BigDecimal.ZERO) < 0) {
            orderIncomeAmt = BigDecimal.ZERO;
        }

        // 查询商家数据，获取商家自有商户id
        BusinessMerchantVo businessMerchantVo = businessMerchantApi.getOwnByBusinessId(businessId, OwnStateEnum.YES.getValue()).unpack();
        Long merchantId = businessMerchantVo.getMerchantId();

        // 生成订单号
        String orderNo = NoUtils.getActiveOrderNo();
        Long orderId = 0L;
        AppUserVo appUserVo = appUserApi.getById(userId).unpack();
        List<TbOrderItemPo> tbOrderItemPos = new ArrayList<>();

        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

        try {
            // 创建订单数据
            TbOrderPo tbOrderPo = new TbOrderPo();
            tbOrderPo.setSignInRequired(activeVo.getSignInRequired());
            tbOrderPo.setBusinessId(activeVo.getBusinessId());
            tbOrderPo.setActiveId(activeId);
            tbOrderPo.setAgentId(agentId);
            tbOrderPo.setAgent2Id(agent2Id);
            tbOrderPo.setUserId(userId);
            tbOrderPo.setActiveShareCode(code);
            tbOrderPo.setOrderNo(orderNo);
            tbOrderPo.setOrderType(getType());
            // 商家自有商户id
            tbOrderPo.setMerchantId(merchantId);
            tbOrderPo.setActiveTitle(activeVo.getActiveTitle());
            tbOrderPo.setActiveImg(activeVo.getActiveImg());
            tbOrderPo.setStartTime(activeVo.getStartTime());
            tbOrderPo.setEndTime(activeVo.getEndTime());
            tbOrderPo.setValidStartTime(activeVo.getValidStartTime());
            tbOrderPo.setValidEndTime(activeVo.getValidEndTime());
            tbOrderPo.setSubsidyState(activeVo.getSubsidyState());
            tbOrderPo.setDiscountState(discountState);
            tbOrderPo.setStepPriceState(activeVo.getStepPriceState());
            tbOrderPo.setAgentState(activeVo.getAgentState());
            tbOrderPo.setVerifyMethod(activeVo.getVerifyMethod());
            tbOrderPo.setTotalStock(activeVo.getTotalStock());
            if (ZeroStateEnum.YES.getValue().equals(zeroState)) {
                // 如果活动需要审核，则状态为待审核状态，需要在商家后台审核
                if (activeVo.getAuditRequired() != null && activeVo.getAuditRequired() == 1) {
                    tbOrderPo.setOrderState(OrderStateEnum.WAIT_AUDIT.getValue());
                    tbOrderPo.setOrderNote(OrderNoteConstant.EIGHT);
                } else {
                    tbOrderPo.setOrderState(OrderStateEnum.WAIT_VERIFY.getValue());
                    tbOrderPo.setPayTime(now);
                }
            } else {
                tbOrderPo.setOrderState(OrderStateEnum.WAIT_PAY.getValue());
            }
            tbOrderPo.setZeroState(zeroState);
            tbOrderPo.setOrderNum(orderNum);
            tbOrderPo.setActivePrice(activeVo.getActivePrice());
            tbOrderPo.setOrderPrice(orderPrice);
            tbOrderPo.setPayPrice(payPrice);
            tbOrderPo.setRedPacketBillId(redPacketBillId);
            tbOrderPo.setRedPacketAmt(redPacketAmt);
            tbOrderPo.setDiscountAmt(discountAmt);
            tbOrderPo.setOrderIncomeAmt(orderIncomeAmt);
            tbOrderPo.setCommissionAmt(activeVo.getCommissionAmt());
            tbOrderPo.setCommissionRate(activeVo.getCommissionRate());
            tbOrderPo.setOtherEquity(otherEquity);
            tbOrderPo.setExclusiveCommissionRate(exclusiveCommissionRate);
            tbOrderPo.setSubAgentCommissionAmt(subAgentCommissionAmt);
            tbOrderPo.setCalCommissionType(calCommissionType);
            tbOrderPo.setActualCommissionAmt(actualCommissionAmt);
            tbOrderPo.setOrderTime(now);
            tbOrderPo.setCreateTime(now);
            tbOrderPo.setUpdateTime(now);
            tbOrderPo.setUserPointsAmt(userPointsAmt);
            tbOrderPo.setAgentPointsAmt(agentPointsAmt);
            tbOrderPo.setSubAgentPointsAmt(subAgentPointsAmt);
            int insert = orderMapper.insert(tbOrderPo);
            if (insert == 0) {
                Throw.isBusinessException("下单失败");
            }
            orderId = tbOrderPo.getId();

            // 签到费用，专属佣金如果高于基础佣金，则签到费用要扣除差值（即签到费用 = 原签到费用 - (专属佣金 - 基础佣金)）
            if (CalCommissionTypeEnum.EXCLUSIVE_COMMISSION.getValue().equals(calCommissionType)
                    && activeVo.getSignInFee().compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal defaultActualCommissionAmt = getDefaultActualCommissionAmt(activeVo, orderPrice, orderNum);
                BigDecimal diff = actualCommissionAmt.subtract(defaultActualCommissionAmt);
                if (diff.compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal newSignInFee = activeVo.getSignInFee()
                            .subtract(diff.divide(BigDecimal.valueOf(orderNum), 2, RoundingMode.DOWN));
                    if (newSignInFee.compareTo(BigDecimal.ZERO) < 0) {
                        newSignInFee = BigDecimal.ZERO;
                    }
                    activeVo.setSignInFee(newSignInFee);
                }
            }
            BigDecimal totalSignInFee = activeVo.getSignInFee().multiply(BigDecimal.valueOf(orderNum));
            // 如果有签到费，商家的订单收入要再减掉签到费（签到费在结算时作为本金收入入账，而订单收入是在所有订单结算后才入账）
            if (activeVo.getSignInFee() != null && activeVo.getSignInFee().compareTo(BigDecimal.ZERO) > 0) {
                orderIncomeAmt = orderIncomeAmt.subtract(totalSignInFee);
            }

            // 报名子单信息
            for (int i = 0; i < orderNum; i++) {
                TbOrderItemPo enrollOrderItem = createOrderItem4Enroll(createOrderDto, activeVo, tbOrderPo, merchantId);
                enrollOrderItem.setItemGroup(i + 1);
                tbOrderItemPos.add(enrollOrderItem);
                insert = orderItemMapper.insert(enrollOrderItem);
                if (insert == 0) {
                    Throw.isBusinessException("下单失败");
                }
            }

            // 需要扣除活动商品库存列表
            List<ActiveGoodsSonDto> activeGoodsSonDtos = new ArrayList<>();

            if (!CollectionUtils.isEmpty(activeGoods)) {
                // 生成核销码
                String verifyCode;
                // 补贴类型(0-未设置,1-自动按比例分摊,2-手动设置)
                Integer subsidyState = activeVo.getSubsidyState();

                // 如果实付金额大于商品总额，则后面计算本金和补贴都以商品总额去计算
                // 如果订单收入大于0（订单收入=实付金额-商品总额-全核销佣金），则商品本金全给，没有补贴
                if (orderIncomeAmt.compareTo(BigDecimal.ZERO) > 0) {
                    for (int i = 0; i < orderNum; i++) {
                        for (ActiveGoodsSonDto activeGood : activeGoods) {
                            Long getMerchantId = activeGood.getMerchantId();
                            String goodsId = activeGood.getGoodsId();
                            BigDecimal goodsPrice = activeGood.getGoodsPrice();
                            Integer goodsNum = activeGood.getGoodsNum();
                            String goodsImgs = activeGood.getGoodsImgs();
                            // 是否是多商户通用券(1-否，2-是)
                            Integer mulState = activeGood.getMulState();
                            if (MulStateEnum.NO.getValue().equals(mulState)) {
                                activeGoodsSonDtos.add(activeGood);
                            }
                            for (int j = 0; j < goodsNum; j++) {
                                // 计算商户订单本金(按比例分配的用户支付的订单款)=商品价格/商品总价 * (实付金额-佣金)
                                BigDecimal merchantAmt = goodsPrice;

                                // 计算总补贴=商品价格-本金
                                BigDecimal totalSubsidyAmt = BigDecimal.ZERO;

                                BigDecimal commissionAmt = BigDecimal.ZERO;
                                BigDecimal orderItemRedPacketAmt = BigDecimal.ZERO;
                                BigDecimal subCommissionAmt = BigDecimal.ZERO;
                                BigDecimal orderItemUserPointsAmt = BigDecimal.ZERO; // 子订单用户可得积分
                                BigDecimal orderItemAgentPointsAmt = BigDecimal.ZERO; // 子订单一级经纪人可得积分
                                BigDecimal orderItemSubAgentPointsAmt = BigDecimal.ZERO; // 子订单二级经纪人可得积分
                                if (totalGoodsPrice.compareTo(BigDecimal.ZERO) > 0) {
                                    // 计算佣金=商品价格/商品总价 * 实付金额 * 佣金比例
                                    //       =商品价格/商品总价 * 佣金（全核销）
//                                    commissionAmt = goodsPrice.multiply(actualCommissionAmt).divide(totalGoodsPrice, 2, BigDecimal.ROUND_DOWN);
//                                    // 计算红包=商品价格/商品总价 * 红包金额
//                                    orderItemRedPacketAmt = goodsPrice.multiply(redPacketAmt).divide(totalGoodsPrice, 2, BigDecimal.ROUND_HALF_UP);

                                    commissionAmt = calculateItemCommissionAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), actualCommissionAmt);
                                    // 二级经纪人可得佣金
                                    subCommissionAmt = commissionAmt.multiply(subAgentCommissionRate).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN);
                                    // 计算红包=商品价格/商品总价 * 红包金额
                                    orderItemRedPacketAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), redPacketAmt);
                                    orderItemUserPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), userPointsAmt);
                                    orderItemAgentPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), agentPointsAmt);
                                    orderItemSubAgentPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), subAgentPointsAmt);
                                }

                                // 计算商户订单补贴(该订单商场补贴的金额)=总补贴-红包
                                BigDecimal merchantSubsidyAmt = BigDecimal.ZERO;

                                // 计算分销金额=商品价格/商品总价 * 实付金额
                                BigDecimal distributionOrderAmt = goodsPrice;

                                // 生成子订单号
                                String subOrderNo = NoUtils.getActiveSubOrderNo();

                                while (true) {
                                    verifyCode = NoUtils.getVerifyCode();
                                    Integer verifyCodeCount = orderItemMapper.selectCount(new QueryWrapper<TbOrderItemPo>().eq("verify_code", verifyCode));
                                    if (verifyCodeCount == null || verifyCodeCount <= 0) {
                                        break;
                                    }
                                }

                                TbOrderItemPo tbOrderItemPo = new TbOrderItemPo();
                                tbOrderItemPo.setItemGroup(i + 1);
                                tbOrderItemPo.setBusinessId(businessId);
                                tbOrderItemPo.setActiveId(activeId);
                                tbOrderItemPo.setAgentId(agentId);
                                tbOrderItemPo.setAgent2Id(agent2Id);
                                tbOrderItemPo.setOrderId(orderId);
                                tbOrderItemPo.setUserId(userId);
                                tbOrderItemPo.setActiveGoodsId(activeGood.getId());
                                tbOrderItemPo.setSubOrderNo(subOrderNo);
                                tbOrderItemPo.setOrderType(getType());
                                // 团购订单所属商户，商品所属商户
                                tbOrderItemPo.setMerchantId(getMerchantId);
                                tbOrderItemPo.setGoodsId(goodsId);
                                tbOrderItemPo.setMulState(mulState);
                                tbOrderItemPo.setGoodsName(activeGood.getGoodsName());
                                tbOrderItemPo.setGoodsImgs(goodsImgs);
                                tbOrderItemPo.setGoodsPrice(goodsPrice);
                                tbOrderItemPo.setGoodsNum(1);
                                tbOrderItemPo.setVerifyCode(verifyCode);
                                tbOrderItemPo.setMerchantAmt(merchantAmt);
                                tbOrderItemPo.setMerchantSubsidyAmt(merchantSubsidyAmt);
                                tbOrderItemPo.setCommissionAmt(commissionAmt);
                                tbOrderItemPo.setSubAgentCommissionAmt(subCommissionAmt);
                                tbOrderItemPo.setRedPacketAmt(orderItemRedPacketAmt);
                                tbOrderItemPo.setTotalSubsidyAmt(totalSubsidyAmt);
                                tbOrderItemPo.setDistributionOrderAmt(distributionOrderAmt);
                                tbOrderItemPo.setReturnAmt(BigDecimal.ZERO);
                                tbOrderItemPo.setSubOrderState(SubOrderStateEnum.WAIT_PAY.getValue());
                                tbOrderItemPo.setSettleState(SettleStateEnum.NO.getValue());
                                tbOrderItemPo.setOrderTime(tbOrderPo.getOrderTime());
                                tbOrderItemPo.setExpireTime(activeVo.getValidEndTime());
                                tbOrderItemPo.setCreateTime(now);
                                tbOrderItemPo.setUpdateTime(now);
                                tbOrderItemPo.setUserPointsAmt(orderItemUserPointsAmt);
                                tbOrderItemPo.setAgentPointsAmt(orderItemAgentPointsAmt);
                                tbOrderItemPo.setSubAgentPointsAmt(orderItemSubAgentPointsAmt);
                                tbOrderItemPo.setPointsSettleState(pointsSettleState);

                                tbOrderItemPo.setVerifyType(activeGood.getVerifyType());
                                tbOrderItemPo.setPftSupplier(activeGood.getPftSupplier());
                                tbOrderItemPo.setPftProduct(activeGood.getPftProduct());
                                tbOrderItemPo.setPftTicket(activeGood.getPftTicket());

                                // 子订单类型
                                tbOrderItemPo.setItemType(OrderItemTypeEnum.GOODS.getValue());

                                if (VerifyTypeEnum.TYF.getValue().equals(tbOrderItemPo.getVerifyType())) {
                                    boolean flag = pftService.orderPreCheck(tbOrderItemPo, appUserVo);
                                    if (!flag) {
                                        Throw.isBusinessException("票付通下单失败");
                                    }
                                }

                                insert = orderItemMapper.insert(tbOrderItemPo);
                                if (insert == 0) {
                                    Throw.isBusinessException("下单失败");
                                }

                                tbOrderItemPos.add(tbOrderItemPo);
                            }
                        }
                    }
                } else {
                    // 计算活动商品补贴
                    if (SubsidyStateEnum.NO.getValue().equals(subsidyState) || SubsidyStateEnum.AUTO.getValue().equals(subsidyState)) {
                        for (int i = 0; i < orderNum; i++) {
                            // 自动按比例分摊
                            for (ActiveGoodsSonDto activeGood : activeGoods) {
                                Long getMerchantId = activeGood.getMerchantId();
                                String goodsId = activeGood.getGoodsId();
                                BigDecimal goodsPrice = activeGood.getGoodsPrice();
                                Integer goodsNum = activeGood.getGoodsNum();
                                String goodsImgs = activeGood.getGoodsImgs();
                                // 是否是多商户通用券(1-否，2-是)
                                Integer mulState = activeGood.getMulState();
                                if (MulStateEnum.NO.getValue().equals(mulState)) {
                                    activeGoodsSonDtos.add(activeGood);
                                }
                                for (int j = 0; j < goodsNum; j++) {
                                    BigDecimal merchantAmt = BigDecimal.ZERO;
                                    BigDecimal commissionAmt = BigDecimal.ZERO;
                                    BigDecimal subCommissionAmt = BigDecimal.ZERO;
                                    BigDecimal orderItemRedPacketAmt = BigDecimal.ZERO;
                                    BigDecimal distributionOrderAmt = BigDecimal.ZERO;
                                    BigDecimal orderItemUserPointsAmt = BigDecimal.ZERO; // 子订单用户可得积分
                                    BigDecimal orderItemAgentPointsAmt = BigDecimal.ZERO; // 子订单一级经纪人可得积分
                                    BigDecimal orderItemSubAgentPointsAmt = BigDecimal.ZERO; // 子订单二级经纪人可得积分
                                    if (totalGoodsPrice.compareTo(BigDecimal.ZERO) > 0) {
                                        // 计算商户订单本金(按比例分配的用户支付的订单款)=商品价格/商品总价 * (实付金额-佣金)
                                        merchantAmt = calculateMerchantAmtIfNeedSubsidy(goodsPrice, totalGoodsPrice, totalSignInFee, tbOrderPo);
                                        // 计算佣金=商品价格/商品总价 * 实付金额 * 佣金比例
                                        //       =商品价格/商品总价 * 佣金（全核销）FIXME
//                                        commissionAmt = goodsPrice.multiply(actualCommissionAmt).divide(totalGoodsPrice, 2, BigDecimal.ROUND_DOWN);
                                        commissionAmt = calculateItemCommissionAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), actualCommissionAmt);
                                        // 二级经纪人可得佣金
                                        subCommissionAmt = commissionAmt.multiply(subAgentCommissionRate).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN);
                                        // 计算红包=商品价格/商品总价 * 红包金额 FIXME
//                                        orderItemRedPacketAmt = goodsPrice.multiply(redPacketAmt).divide(totalGoodsPrice, 2, BigDecimal.ROUND_HALF_UP);
                                        orderItemRedPacketAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), redPacketAmt);
                                        orderItemUserPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), userPointsAmt);
                                        orderItemAgentPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), agentPointsAmt);
                                        orderItemSubAgentPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), subAgentPointsAmt);

                                        // 计算分销金额=商品价格/商品总价 * 实付金额
                                        distributionOrderAmt = goodsPrice.multiply(payPrice.subtract(totalSignInFee)).divide(totalGoodsPrice, 2, BigDecimal.ROUND_HALF_UP);
                                    }

                                    // 计算总补贴=商品价格-本金
                                    BigDecimal totalSubsidyAmt = goodsPrice.subtract(merchantAmt);


                                    // 计算商户订单补贴(该订单商场补贴的金额)=总补贴-红包
                                    BigDecimal merchantSubsidyAmt = totalSubsidyAmt.subtract(orderItemRedPacketAmt);

                                    // 生成子订单号
                                    String subOrderNo = NoUtils.getActiveSubOrderNo();

                                    while (true) {
                                        verifyCode = NoUtils.getVerifyCode();
                                        Integer verifyCodeCount = orderItemMapper.selectCount(new QueryWrapper<TbOrderItemPo>().eq("verify_code", verifyCode));
                                        if (verifyCodeCount == null || verifyCodeCount <= 0) {
                                            break;
                                        }
                                    }

                                    TbOrderItemPo tbOrderItemPo = new TbOrderItemPo();
                                    tbOrderItemPo.setItemGroup(i + 1);
                                    tbOrderItemPo.setBusinessId(businessId);
                                    tbOrderItemPo.setActiveId(activeId);
                                    tbOrderItemPo.setAgentId(agentId);
                                    tbOrderItemPo.setAgent2Id(agent2Id);
                                    tbOrderItemPo.setOrderId(orderId);
                                    tbOrderItemPo.setUserId(userId);
                                    tbOrderItemPo.setActiveGoodsId(activeGood.getId());
                                    tbOrderItemPo.setSubOrderNo(subOrderNo);
                                    tbOrderItemPo.setOrderType(getType());
                                    // 团购订单所属商户，商品所属商户
                                    tbOrderItemPo.setMerchantId(getMerchantId);
                                    tbOrderItemPo.setGoodsId(goodsId);
                                    tbOrderItemPo.setMulState(mulState);
                                    tbOrderItemPo.setGoodsName(activeGood.getGoodsName());
                                    tbOrderItemPo.setGoodsImgs(goodsImgs);
                                    tbOrderItemPo.setGoodsPrice(goodsPrice);
                                    tbOrderItemPo.setGoodsNum(1);
                                    tbOrderItemPo.setVerifyCode(verifyCode);
                                    tbOrderItemPo.setMerchantAmt(merchantAmt);
                                    tbOrderItemPo.setMerchantSubsidyAmt(merchantSubsidyAmt);
                                    tbOrderItemPo.setCommissionAmt(commissionAmt);
                                    tbOrderItemPo.setSubAgentCommissionAmt(subCommissionAmt);
                                    tbOrderItemPo.setRedPacketAmt(orderItemRedPacketAmt);
                                    tbOrderItemPo.setTotalSubsidyAmt(totalSubsidyAmt);
                                    tbOrderItemPo.setDistributionOrderAmt(distributionOrderAmt);
                                    tbOrderItemPo.setReturnAmt(BigDecimal.ZERO);
                                    tbOrderItemPo.setSubOrderState(ZeroStateEnum.YES.getValue().equals(zeroState)
                                            ? SubOrderStateEnum.WAIT_VERIFY.getValue()
                                            : SubOrderStateEnum.WAIT_PAY.getValue());

                                    if (tbOrderPo.getOrderState().equals(OrderStateEnum.WAIT_AUDIT.getValue())) {
                                        tbOrderItemPo.setSubOrderState(SubOrderStateEnum.WAIT_AUDIT.getValue());
                                    }

                                    tbOrderItemPo.setZeroState(zeroState);
                                    tbOrderItemPo.setSettleState(SettleStateEnum.NO.getValue());
                                    tbOrderItemPo.setOrderTime(tbOrderPo.getOrderTime());
                                    tbOrderItemPo.setExpireTime(activeVo.getValidEndTime());
                                    tbOrderItemPo.setCreateTime(now);
                                    tbOrderItemPo.setUpdateTime(now);
                                    tbOrderItemPo.setUserPointsAmt(orderItemUserPointsAmt);
                                    tbOrderItemPo.setAgentPointsAmt(orderItemAgentPointsAmt);
                                    tbOrderItemPo.setSubAgentPointsAmt(orderItemSubAgentPointsAmt);
                                    tbOrderItemPo.setPointsSettleState(pointsSettleState);

                                    tbOrderItemPo.setVerifyType(activeGood.getVerifyType());
                                    tbOrderItemPo.setPftSupplier(activeGood.getPftSupplier());
                                    tbOrderItemPo.setPftProduct(activeGood.getPftProduct());
                                    tbOrderItemPo.setPftTicket(activeGood.getPftTicket());

                                    // 子订单类型
                                    tbOrderItemPo.setItemType(OrderItemTypeEnum.GOODS.getValue());

                                    if (VerifyTypeEnum.TYF.getValue().equals(tbOrderItemPo.getVerifyType())) {
                                        boolean flag = pftService.orderPreCheck(tbOrderItemPo, appUserVo);
                                        if (!flag) {
                                            Throw.isBusinessException("票付通下单失败");
                                        }
                                    }

                                    insert = orderItemMapper.insert(tbOrderItemPo);
                                    if (insert == 0) {
                                        Throw.isBusinessException("下单失败");
                                    }

                                    tbOrderItemPos.add(tbOrderItemPo);
                                }
                            }
                        }
                    } else if (SubsidyStateEnum.MANUAL.getValue().equals(subsidyState)) {
                        Map<String, List<ActiveGoodsSonDto>> activeGoodsMap = new HashMap<>();
                        if (!CollectionUtils.isEmpty(activeGoods)) {
                            activeGoodsMap = activeGoods.stream().collect(Collectors.groupingBy(ActiveGoodsSonDto::getGoodsId));
                        }

                        Map<String, List<ActiveGoodsSonDto>> activeGoodsSonDtoMap = new HashMap<>();
                        // 手动设置
                        for (int i = 0; i < orderNum; i++) {
                            for (ActiveGoodsSubsidySonDto activeGoodsSubsidySonDto : activeGoodsSubsidy) {
                                Long getMerchantId = activeGoodsSubsidySonDto.getMerchantId();
                                String goodsId = activeGoodsSubsidySonDto.getGoodsId();
                                BigDecimal goodsPrice = activeGoodsSubsidySonDto.getGoodsPrice();
                                // 是否是多商户通用券(1-否，2-是)
                                Integer mulState = activeGoodsSubsidySonDto.getMulState();
                                if (MulStateEnum.NO.getValue().equals(mulState) && !StringUtils.isEmpty(goodsId)) {
                                    List<ActiveGoodsSonDto> activeGoodsSonDtoList = activeGoodsSonDtoMap.get(goodsId);
                                    if (CollectionUtils.isEmpty(activeGoodsSonDtoList)) {
                                        activeGoodsSonDtoList = new ArrayList<>();
                                    }

                                    ActiveGoodsSonDto activeGoodsSonDto = new ActiveGoodsSonDto();
                                    activeGoodsSonDto.setGoodsId(goodsId);
                                    activeGoodsSonDto.setGoodsNum(1);
                                    activeGoodsSonDtoList.add(activeGoodsSonDto);

                                    activeGoodsSonDtoMap.put(goodsId, activeGoodsSonDtoList);
                                }

                                Long activeGoodsId = 0L;
                                if (!StringUtils.isEmpty(goodsId)) {
                                    List<ActiveGoodsSonDto> activeGoodsSons = activeGoodsMap.get(goodsId);
                                    if (!CollectionUtils.isEmpty(activeGoodsSons)) {
                                        ActiveGoodsSonDto activeGoodsSonDto = activeGoodsSons.get(0);
                                        activeGoodsId = activeGoodsSonDto.getId();
                                    }
                                }

                                // 商户订单本金(按比例分配的用户支付的订单款)
                                BigDecimal merchantAmt = BigDecimal.ZERO;
                                // 总补贴
                                BigDecimal totalSubsidyAmt = BigDecimal.ZERO;
                                // 佣金
                                BigDecimal commissionAmt = BigDecimal.ZERO;
                                BigDecimal subCommissionAmt = BigDecimal.ZERO;
                                // 红包
                                BigDecimal orderItemRedPacketAmt = BigDecimal.ZERO;
                                // 商户订单补贴(该订单商场补贴的金额)
                                BigDecimal merchantSubsidyAmt = BigDecimal.ZERO;
                                // 分销金额
                                BigDecimal distributionOrderAmt = BigDecimal.ZERO;
                                BigDecimal orderItemUserPointsAmt = BigDecimal.ZERO; // 子订单用户可得积分
                                BigDecimal orderItemAgentPointsAmt = BigDecimal.ZERO; // 子订单一级经纪人可得积分
                                BigDecimal orderItemSubAgentPointsAmt = BigDecimal.ZERO; // 子订单二级经纪人可得积分

                                // 如果是专属佣金，则按照自动比例去计算，否则，则按照手动设置去计算
                                if (CalCommissionTypeEnum.EXCLUSIVE_COMMISSION.getValue().equals(calCommissionType)) {
                                    if (totalGoodsPrice.compareTo(BigDecimal.ZERO) > 0) {
                                        // 计算商户订单本金(按比例分配的用户支付的订单款)=商品价格/商品总价 * (实付金额-佣金或专属佣金)
                                        merchantAmt = calculateMerchantAmtIfNeedSubsidy(goodsPrice, totalGoodsPrice, totalSignInFee, tbOrderPo);

                                        // 计算佣金=商品价格/商品总价 * 实付金额 * 佣金比例
                                        //       =商品价格/商品总价 * 佣金（全核销）FIXME
//                                        commissionAmt = goodsPrice.multiply(actualCommissionAmt).divide(totalGoodsPrice, 2, BigDecimal.ROUND_DOWN);
                                        commissionAmt = calculateItemCommissionAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), actualCommissionAmt);
                                        // 二级经纪人可得佣金
                                        subCommissionAmt = commissionAmt.multiply(subAgentCommissionRate).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN);

                                        // 计算红包=商品价格/商品总价 * 红包金额 FIXME
//                                        orderItemRedPacketAmt = goodsPrice.multiply(redPacketAmt).divide(totalGoodsPrice, 2, BigDecimal.ROUND_HALF_UP);
                                        orderItemRedPacketAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), redPacketAmt);
                                        orderItemUserPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), userPointsAmt);
                                        orderItemAgentPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), agentPointsAmt);
                                        orderItemSubAgentPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), subAgentPointsAmt);
                                    }

                                    // 计算总补贴=商品价格-商户订单本金
                                    totalSubsidyAmt = goodsPrice.subtract(merchantAmt);

                                    // 计算商户订单补贴(该订单商场补贴的金额)=总补贴-红包
                                    merchantSubsidyAmt = totalSubsidyAmt.subtract(orderItemRedPacketAmt);
                                } else {
                                    // 手动设置补贴金额
                                    BigDecimal subsidyAmt = activeGoodsSubsidySonDto.getSubsidyAmt() == null ? BigDecimal.ZERO : activeGoodsSubsidySonDto.getSubsidyAmt();
                                    // 计算商户订单本金(按比例分配的用户支付的订单款)=商品价格-手动设置补贴金额
                                    merchantAmt = goodsPrice.subtract(subsidyAmt);

                                    // 计算总补贴=商品价格-商户订单本金
                                    totalSubsidyAmt = goodsPrice.subtract(merchantAmt);

                                    if (totalGoodsPrice.compareTo(BigDecimal.ZERO) > 0) {
                                        // 计算佣金=商品价格/商品总价 * 实付金额 * 佣金比例
                                        //       =商品价格/商品总价 * 佣金（全核销）FIXME
//                                        commissionAmt = goodsPrice.multiply(actualCommissionAmt).divide(totalGoodsPrice, 2, BigDecimal.ROUND_DOWN);
                                        commissionAmt = calculateItemCommissionAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), actualCommissionAmt);
                                        // 二级经纪人可得佣金
                                        subCommissionAmt = commissionAmt.multiply(subAgentCommissionRate).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN);

                                        // 计算红包=商品价格/商品总价 * 红包金额 FIXME
//                                        orderItemRedPacketAmt = goodsPrice.multiply(redPacketAmt).divide(totalGoodsPrice, 2, BigDecimal.ROUND_HALF_UP);
                                        orderItemRedPacketAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), redPacketAmt);
                                        orderItemUserPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), userPointsAmt);
                                        orderItemAgentPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), agentPointsAmt);
                                        orderItemSubAgentPointsAmt = calculateItemRedPacketAmt(goodsPrice, totalGoodsPrice.add(totalSignInFee), subAgentPointsAmt);

                                        // 计算分销金额=商品价格/商品总价 * 实付金额
                                        distributionOrderAmt = goodsPrice.multiply(payPrice).divide(totalGoodsPrice.add(totalSignInFee), 2, BigDecimal.ROUND_HALF_UP);
                                    }

                                    // 计算商户订单补贴(该订单商场补贴的金额)=手动设置补贴金额
                                    merchantSubsidyAmt = subsidyAmt;
                                }

                                // 生成子订单号
                                String subOrderNo = NoUtils.getActiveSubOrderNo();

                                while (true) {
                                    verifyCode = NoUtils.getVerifyCode();
                                    Integer verifyCodeCount = orderItemMapper.selectCount(new QueryWrapper<TbOrderItemPo>().eq("verify_code", verifyCode));
                                    if (verifyCodeCount == null || verifyCodeCount <= 0) {
                                        break;
                                    }
                                }

                                TbOrderItemPo tbOrderItemPo = new TbOrderItemPo();
                                tbOrderItemPo.setItemGroup(i + 1);
                                tbOrderItemPo.setBusinessId(businessId);
                                tbOrderItemPo.setActiveId(activeId);
                                tbOrderItemPo.setAgentId(agentId);
                                tbOrderItemPo.setAgent2Id(agent2Id);
                                tbOrderItemPo.setOrderId(orderId);
                                tbOrderItemPo.setUserId(userId);
                                tbOrderItemPo.setActiveGoodsId(activeGoodsId);
                                tbOrderItemPo.setSubOrderNo(subOrderNo);
                                tbOrderItemPo.setOrderType(getType());
                                tbOrderItemPo.setMerchantId(getMerchantId);
                                tbOrderItemPo.setGoodsId(goodsId);
                                tbOrderItemPo.setMulState(mulState);
                                tbOrderItemPo.setGoodsName(activeGoodsSubsidySonDto.getGoodsName());
                                tbOrderItemPo.setGoodsImgs(activeGoodsSubsidySonDto.getGoodsImgs());
                                tbOrderItemPo.setGoodsPrice(goodsPrice);
                                tbOrderItemPo.setGoodsNum(1);
                                tbOrderItemPo.setVerifyCode(verifyCode);
                                tbOrderItemPo.setMerchantAmt(merchantAmt);
                                tbOrderItemPo.setMerchantSubsidyAmt(merchantSubsidyAmt);
                                tbOrderItemPo.setCommissionAmt(commissionAmt);
                                tbOrderItemPo.setSubAgentCommissionAmt(subCommissionAmt);
                                tbOrderItemPo.setRedPacketAmt(orderItemRedPacketAmt);
                                tbOrderItemPo.setTotalSubsidyAmt(totalSubsidyAmt);
                                tbOrderItemPo.setDistributionOrderAmt(distributionOrderAmt);
                                tbOrderItemPo.setReturnAmt(BigDecimal.ZERO);
                                tbOrderItemPo.setSubOrderState(SubOrderStateEnum.WAIT_PAY.getValue());
                                tbOrderItemPo.setSettleState(SettleStateEnum.NO.getValue());
                                tbOrderItemPo.setOrderTime(tbOrderPo.getOrderTime());
                                tbOrderItemPo.setExpireTime(activeVo.getValidEndTime());
                                tbOrderItemPo.setCreateTime(now);
                                tbOrderItemPo.setUpdateTime(now);
                                tbOrderItemPo.setUserPointsAmt(orderItemUserPointsAmt);
                                tbOrderItemPo.setAgentPointsAmt(orderItemAgentPointsAmt);
                                tbOrderItemPo.setSubAgentPointsAmt(orderItemSubAgentPointsAmt);
                                tbOrderItemPo.setPointsSettleState(pointsSettleState);

                                // 子订单类型
                                tbOrderItemPo.setItemType(OrderItemTypeEnum.GOODS.getValue());

                                tbOrderItemPo.setVerifyType(VerifyTypeEnum.SYS.getValue());

                                insert = orderItemMapper.insert(tbOrderItemPo);
                                if (insert == 0) {
                                    Throw.isBusinessException("下单失败");
                                }

                                tbOrderItemPos.add(tbOrderItemPo);
                            }
                        }

                        if (!CollectionUtils.isEmpty(activeGoodsSonDtoMap)) {
                            for (List<ActiveGoodsSonDto> value : activeGoodsSonDtoMap.values()) {
                                activeGoodsSonDtos.addAll(value);
                            }
                        }
                    }
                }
            }

            // 扣减活动库存，以及更新红包使用状态和使用时间
            ActiveSubStockDto activeSubStockDto = new ActiveSubStockDto();
            activeSubStockDto.setActiveId(activeId);
            activeSubStockDto.setNum(orderNum);
            activeSubStockDto.setActiveRedPacketBillPageVo(activeRedPacketBillPageVo);
            activeSubStockDto.setActiveGoodsSonDtos(activeGoodsSonDtos);
            boolean subResult = activeApi.subActiveStock(activeSubStockDto).unpack();
            if (!subResult) {
                Throw.isBusinessException("活动库存不足");
            }

            transactionManager.commit(transaction);
        } catch (Exception e) {
            //回滚事务
            transactionManager.rollback(transaction);
            log.error("<创建团购活动订单>事务异常回滚", e);
            Throw.isBusinessException(e.getMessage());
        }

        // 校验子订单佣金累加是否等于全核销佣金
        if (actualCommissionAmt != null && actualCommissionAmt.compareTo(BigDecimal.ZERO) > 0 && !CollectionUtils.isEmpty(tbOrderItemPos)) {
            // 累计子订单佣金
            BigDecimal sonTotalCommissionAmt = BigDecimal.ZERO;

            for (TbOrderItemPo tbOrderItemPo : tbOrderItemPos) {
                BigDecimal commissionAmt = tbOrderItemPo.getCommissionAmt();
                if (commissionAmt != null && commissionAmt.compareTo(BigDecimal.ZERO) > 0) {
                    sonTotalCommissionAmt = sonTotalCommissionAmt.add(commissionAmt);
                }
            }

            if (sonTotalCommissionAmt.compareTo(actualCommissionAmt) < 0) {
                TbOrderItemPo tbOrderItemPo = tbOrderItemPos.get(tbOrderItemPos.size() - 1);
                BigDecimal amt = tbOrderItemPo.getCommissionAmt().add(actualCommissionAmt.subtract(sonTotalCommissionAmt));
                BigDecimal subAmt = amt.multiply(subAgentCommissionRate).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN);
                tbOrderItemPo.setCommissionAmt(amt);
                tbOrderItemPo.setSubAgentCommissionAmt(subAmt);
                orderItemMapper.updateById(tbOrderItemPo);
            }
        }

        CreateOrderVo createOrderVo = new CreateOrderVo();
        createOrderVo.setOrderId(orderId);
        createOrderVo.setOrderNo(orderNo);
        createOrderVo.setZeroState(zeroState);
        createOrderVo.setInviteReturnMsg(getInviteReturnMsg(activeVo, orderNum));

        return createOrderVo;
    }

    @Override
    public CreateOrderVo createPointsOrder(CreateOrderDto createOrderDto, BusinessPointsMallProductVo productVo) {
        return null;
    }

    // 计算商户本金
    private BigDecimal calculateMerchantAmtIfNeedSubsidy(BigDecimal goodsPrice, BigDecimal totalGoodsPrice, BigDecimal totalSignInFee, TbOrderPo order) {
        // 剩余基础本金 = 用户支付金额 - 佣金 - 签到费
        BigDecimal baseAmt = order.getPayPrice().subtract(order.getActualCommissionAmt()).subtract(totalSignInFee);
        return goodsPrice.multiply(baseAmt)
                .divide(totalGoodsPrice, 2, RoundingMode.HALF_UP);
    }

    private BigDecimal getTotalGoodsPrice(List<ActiveGoodsSonDto> activeGoods, Integer orderNum) {
        BigDecimal totalGoodsPrice = BigDecimal.ZERO;
        if (!CollectionUtils.isEmpty(activeGoods)) {
            for (ActiveGoodsSonDto activeGood : activeGoods) {
                BigDecimal goodsPrice = activeGood.getGoodsPrice();
                Integer goodsNum = activeGood.getGoodsNum();

                totalGoodsPrice = totalGoodsPrice.add(goodsPrice.multiply(new BigDecimal(goodsNum)));
            }

            totalGoodsPrice = totalGoodsPrice.multiply(new BigDecimal(String.valueOf(orderNum)));
        }
        return totalGoodsPrice;
    }

    private TbOrderItemPo createOrderItem4Enroll(CreateOrderDto createOrderDto, ActiveVo activeVo, TbOrderPo orderPo, Long businessMerchantId) {
        TbOrderItemPo tbOrderItemPo = new TbOrderItemPo();
        tbOrderItemPo.setBusinessId(activeVo.getBusinessId());
        tbOrderItemPo.setActiveId(activeVo.getId());
        tbOrderItemPo.setAgentId(orderPo.getAgentId());
        tbOrderItemPo.setOrderId(orderPo.getId());
        tbOrderItemPo.setUserId(orderPo.getUserId());
        tbOrderItemPo.setSubOrderNo(NoUtils.getActiveSubOrderNo());
        tbOrderItemPo.setOrderType(getType());
        tbOrderItemPo.setMerchantId(businessMerchantId);
        tbOrderItemPo.setGoodsId("");
        tbOrderItemPo.setGoodsName(activeVo.getActiveTitle());
        tbOrderItemPo.setGoodsImgs(activeVo.getActiveImg());

        if (activeVo.getSignInRequired() == SignInStatusEnum.NEED.getValue()) {
            tbOrderItemPo.setVerifyCode(generateVerifyCode());
        }

        tbOrderItemPo.setGoodsPrice(activeVo.getSignInFee());
        tbOrderItemPo.setGoodsNum(1);
        tbOrderItemPo.setMerchantAmt(activeVo.getSignInFee());
        tbOrderItemPo.setMerchantSubsidyAmt(BigDecimal.ZERO);
        // 平摊的佣金
        BigDecimal totalGoodsPrice = getTotalGoodsPrice(activeVo.getActiveGoods(), orderPo.getOrderNum());
        BigDecimal totalSignInFee = activeVo.getSignInFee().multiply(BigDecimal.valueOf(orderPo.getOrderNum()));
        BigDecimal totalPrice = totalGoodsPrice.add(totalSignInFee);
        tbOrderItemPo.setCommissionAmt(calculateItemCommissionAmt(activeVo.getSignInFee(), totalPrice, orderPo.getActualCommissionAmt()));
        tbOrderItemPo.setSubAgentCommissionAmt(calculateItemCommissionAmt(activeVo.getSignInFee(), totalPrice, orderPo.getSubAgentCommissionAmt()));
        // 平摊积分
        tbOrderItemPo.setUserPointsAmt(calculateItemRedPacketAmt(activeVo.getSignInFee(), totalPrice, orderPo.getUserPointsAmt()));
        tbOrderItemPo.setAgentPointsAmt(calculateItemRedPacketAmt(activeVo.getSignInFee(), totalPrice, orderPo.getAgentPointsAmt()));
        tbOrderItemPo.setSubAgentPointsAmt(calculateItemRedPacketAmt(activeVo.getSignInFee(), totalPrice, orderPo.getSubAgentPointsAmt()));
        // 平摊的红包额度
        // 计算红包=商品价格/商品总价 * 红包金额
        tbOrderItemPo.setRedPacketAmt(calculateItemRedPacketAmt(activeVo.getSignInFee(), totalPrice, orderPo.getRedPacketAmt()));
        tbOrderItemPo.setTotalSubsidyAmt(BigDecimal.ZERO);
        tbOrderItemPo.setDistributionOrderAmt(activeVo.getSignInFee());
        tbOrderItemPo.setReturnAmt(BigDecimal.ZERO);
        tbOrderItemPo.setSubOrderState(ZeroStateEnum.YES.getValue().equals(activeVo.getZeroState())
                ? SubOrderStateEnum.WAIT_VERIFY.getValue()
                : SubOrderStateEnum.WAIT_PAY.getValue());
        // 待审核
        if (orderPo.getOrderState().equals(OrderStateEnum.WAIT_AUDIT.getValue())) {
            tbOrderItemPo.setSubOrderState(SubOrderStateEnum.WAIT_AUDIT.getValue());
        }

        tbOrderItemPo.setZeroState(activeVo.getZeroState());
        tbOrderItemPo.setSettleState(SettleStateEnum.NO.getValue());
        tbOrderItemPo.setOrderTime(orderPo.getOrderTime());
        tbOrderItemPo.setExpireTime(activeVo.getValidEndTime());
        List<ActiveEnrollInfoSonDto> activeEnrollInfos = createOrderDto.getActiveEnrollInfos();
        tbOrderItemPo.setEnrollInfo(CollectionUtils.isEmpty(activeEnrollInfos) ? "" : JSON.toJSONString(activeEnrollInfos));
        tbOrderItemPo.setCreateTime(LocalDateTime.now());
        tbOrderItemPo.setUpdateTime(LocalDateTime.now());

        tbOrderItemPo.setVerifyType(activeVo.getVerifyType());
        tbOrderItemPo.setPftSupplier(activeVo.getPftSupplier());
        tbOrderItemPo.setPftProduct(activeVo.getPftProduct());
        tbOrderItemPo.setPftTicket(activeVo.getPftTicket());

        // 子订单类型
        tbOrderItemPo.setItemType(OrderItemTypeEnum.SIGN_IN.getValue());

        return tbOrderItemPo;
    }

    private String generateVerifyCode() {
        String verifyCode = "";
        while (true) {
            verifyCode = NoUtils.getVerifyCode();
            Integer verifyCodeCount = orderItemMapper.selectCount(new QueryWrapper<TbOrderItemPo>().eq("verify_code", verifyCode));
            if (verifyCodeCount == null || verifyCodeCount <= 0) {
                break;
            }
        }
        return verifyCode;
    }

    /**
     * 计算子单摊到的佣金
     *
     * @param itemAmt 子单金额
     * @param totalAmt 总金额
     * @param commissionAmt 总佣金
     * @return
     */
    private BigDecimal calculateItemCommissionAmt(BigDecimal itemAmt, BigDecimal totalAmt, BigDecimal commissionAmt) {
        if (itemAmt.compareTo(BigDecimal.ZERO) == 0 || commissionAmt.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        // 计算佣金=商品价格/商品总价 * 实付金额 * 佣金比例
        //       =商品价格/商品总价 * 佣金（全核销）
        return itemAmt.multiply(commissionAmt).divide(totalAmt, 2, BigDecimal.ROUND_DOWN);
    }

    private BigDecimal calculateItemRedPacketAmt(BigDecimal itemAmt, BigDecimal totalAmt, BigDecimal redPacketAmt) {
        return itemAmt.multiply(redPacketAmt).divide(totalAmt, 2, BigDecimal.ROUND_HALF_UP);
    }

    // 活动默认佣金金额
    private BigDecimal getDefaultActualCommissionAmt(ActiveVo activeVo, BigDecimal orderPrice, Integer orderNum) {
        Integer defaultCommissionType = activeVo.getDefaultCommissionType();
        if (defaultCommissionType != null) {
            if (DefaultCommissionTypeEnum.COMMISSION.getValue().equals(defaultCommissionType)) {
                // 实际全核销佣金金额=固定佣金*下单数量
                return activeVo.getCommissionAmt().multiply(new BigDecimal(String.valueOf(orderNum)));
            } else if (DefaultCommissionTypeEnum.COMMISSION_RATE.getValue().equals(defaultCommissionType)) {
                // 实际全核销佣金金额=售价*固定佣金比例
                return orderPrice.multiply(activeVo.getCommissionRate()).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_DOWN);
            }
        }
        return BigDecimal.ZERO;
    }

    private String getInviteReturnMsg(ActiveVo activeVo, Integer orderNum) {
        if (!StepPriceStateEnum.YES.getValue().equals(activeVo.getStepPriceState())) {
            return "";
        }
        // 查询再邀x人，可返x元
        String inviteReturnMsg = "";
        List<ActiveStepPriceSonDto> activeStepPrices = activeVo.getActiveStepPrices();
        if (CollectionUtils.isEmpty(activeStepPrices)) {
            return "";
        }

        // 当前报名活动已经报名成功的用户数
        int enrolledNum = 0;

        // 根据活动id查询阶梯价格数据
        List<TbOrderItemPo> activeEnrollOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                .eq("active_id", activeVo.getId()));
        if (!CollectionUtils.isEmpty(activeEnrollOrderItemPos)) {
            // 过滤符合报名条件的用户（只要在活动结束前没取消的都算，活动结束后取消也算）
            for (TbOrderItemPo orderItemPo : activeEnrollOrderItemPos) {
                // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
                if (SubOrderStateEnum.CANCEL.getValue().equals(orderItemPo.getSubOrderState())
                        && activeVo.getEndTime().isAfter(orderItemPo.getCancelTime())) {
                    continue;
                }

                enrolledNum += 1;
            }
            // 当前总报名用户数=已报名用户+当前下单人数
            enrolledNum += orderNum;
        }

        // 根据阶梯报名人数正序
        activeStepPrices = activeStepPrices.stream()
                .sorted(Comparator.comparing(ActiveStepPriceSonDto::getEnrollNum))
                .collect(Collectors.toList());

        ActiveStepPriceSonDto activeStepPrice = activeStepPrices.get(0);
        Integer firstEnrollNum = activeStepPrice.getEnrollNum();
        if (enrolledNum < firstEnrollNum) {
            // 报名成功，未满第一档人数，支付完成后提示：还差x人即可开启活动
            inviteReturnMsg = String.format("还差%s人即可开启活动", firstEnrollNum - enrolledNum);
        } else {
            // 报名成功，满第一档人数，支付完成后提示：再邀x人，可返y元（对比第二档人数，逐级判断）
            BigDecimal activePrice = activeVo.getActivePrice();
            // 再邀x人
            int inviteNum = 0;
            // 可返x元
            BigDecimal returnAmt = BigDecimal.ZERO;
            for (ActiveStepPriceSonDto activeStepPriceSonDto : activeStepPrices) {
                Integer enrollNum = activeStepPriceSonDto.getEnrollNum();
                BigDecimal enrollPrice = activeStepPrice.getEnrollPrice();

                // 取下一阶级的报名人数对比，如果都没匹配上，则表示已满员
                if (enrolledNum < enrollNum) {
                    // 计算再邀人数=下一阶级报名人数-已报名人数
                    inviteNum = enrollNum - enrolledNum;
                    // 计算可返金额=当前报名价格-对应阶级报名价格
                    returnAmt = activePrice.subtract(enrollPrice);
                    break;
                }
            }

            if (inviteNum != 0 && returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                inviteReturnMsg = String.format("再邀%s人，可返%s元", inviteNum, returnAmt);
            }
        }
        return inviteReturnMsg;
    }

}
